// sm4_cbc_demo.c
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <gmssl/sm4.h>

// XOR 两个 16 字节块
void xor16(uint8_t out[16], const uint8_t a[16], const uint8_t b[16]) {
    for (int i = 0; i < 16; i++) {
        out[i] = a[i] ^ b[i];
    }
}

void print_hex(const char* label, const uint8_t *data, size_t len) {
    printf("%s: ", label);
    for (size_t i = 0; i < len; i++) {
        printf("%02x", data[i]);
    }
    printf("\n");
}

int main(void) {
    const uint8_t key[16] = "0123456789abcdef";
    const uint8_t iv[16]  = "1234567890abcdef";
    const char *msg = "Hello, SM4-CBC!"; // 16 字节
    size_t msg_len = strlen(msg); // = 16

    uint8_t ciphertext[16];
    uint8_t plaintext[16];

    SM4_KEY sm4_key;

    // === 手动 CBC 加密 ===
    sm4_set_encrypt_key(&sm4_key, key);
    uint8_t prev[16];
    memcpy(prev, iv, 16);

    uint8_t temp[16];
    xor16(temp, (const uint8_t *)msg, prev);      // P XOR IV
    sm4_encrypt(&sm4_key, temp, ciphertext);      // E(P XOR IV)
    // prev = ciphertext （但这里只有一块，无需更新）

    print_hex("SM4-CBC Ciphertext", ciphertext, 16);

    // === 手动 CBC 解密 ===
    sm4_set_decrypt_key(&sm4_key, key);
    memcpy(prev, iv, 16);

    sm4_encrypt(&sm4_key, ciphertext, temp);      // D(C)
    xor16(plaintext, temp, prev);                 // D(C) XOR IV
    plaintext[16] = '\0';
    printf("Decrypted: %s\n", plaintext);

    return 0;
}
